﻿//参数包中的三个点做参数数据的时候在"()"的后面,有时放在()里面，有时放在()的后面，即()...
//例一:
//forward<_Valty>(_Val)...) 
//例二: 
//template <class T>
//void PrintArg(T t)
//{
//	cout << t << " ";
//}
//不用逗号表达式要调用以下函数模板
//template <class T>
//int PrintArg(T t)
//{
//	cout << t << " ";
//	return 0; //为了给数组传递数值
//}
////展开函数
//template <class ...Args>
//void ShowList(Args... args)
//{
//	int arr[] = { (PrintArg(args), 0)... }; //或PrintArg(args)...,因为接收的是单个参数
//	cout << endl;
//}
//例三:
//void _func(const T& data, Args ...args)
//{
//	cout << data << " ";
//	_func(args...); //放在里面，因为接收的是参数包
//}
// 
//做为类型参数的时候放在左边
//template <class ...Args> //“...”放在参数包Args的左边，表示中间有N个参数打包成了Args
/*“...”表示参数包中有N个类型，
为每个类型在Args中生成一个对应的函数参数, 将其打包成args*/
//void ShowList(Args... args) 

//template <class T>
//void PrintArg(T t)
//{
//	cout << t << " ";
//}
////展开函数
//template <class ...Args>
//void ShowList(Args... args)
//{
//	int arr[] = { (PrintArg(args), 0)... }; /*使用逗号表达式(PrintArg(args), 0)...
//	展开参数包args中参数，直到参数包为空运用时，
//	{(_Func(args), 0)...}将会展开成{(_Func(arg1),0), (_Func(arg2), 0), (Func(arg3), 0), ... )，
//	最终会创建一个元素值都为0的数组int arr[sizeof...(Args)]。由于是逗号表达式，
//	在创建数组的过程中会先执行逗号表达式前面的部分_Func(args)打印出参数，
//	也就是说在构造int数组的过程中就将参数包展开了，
//	这个数组的目的纯粹是为了在数组构造的过程展开参数包*/
//	cout << endl;
//}
//int main()
//{
//	//ShowList();
//	ShowList(1);
//	ShowList(1, 'A');
//	ShowList(1, 'A', std::string("sort"));
//	return 0;
//}

//template <class T>
//int PrintArg(T t)
//{
//	cout << t << " ";
//	return 0;
//}
////展开函数
//template <class ...Args>
//void ShowList(Args... args)
//{
//	int arr[] = { PrintArg(args)... };
//
//	cout << endl;
//}
////
////int main()
////{
////	ShowList(1);
////	ShowList(1, 'A');
////	ShowList(1, 'A', std::string("sort"));
////
////	return 0;
////}

//template <typename ...Args>
//void Func(Args&&... args)
//{
//	int a[] = { (forward<Args>(args), 0)... };
//	cout << sizeof(a) / sizeof(int) << endl;
//}
//int main()
//{
//	Func(1, 'A', "as", std::string("abc"));
//	return 0;
//}

//class Person
//{
//public:
//	Person(std::string name = "", int age = 0)
//		: name_(name)
//		, age_(age)
//	{}
//	Person(const Person& it)
//		: name_(it.name_)
//		, age_(it.age_)
//	{}
//	std::string name_;
//	int age_;
//};
//template<class T>
//struct ListNode
//{
//	T _data;
//	//const左值构造
//	ListNode(const T& x = T())
//		: _data(x)
//	{}
//	////移动构造
//	//ListNode(T&& x)
//	//	: _data(forward<T>(x))
//	//{}
//	//万能引用构造
//	template<class ...Args>
//	ListNode(Args&&... args)
//		: _data(forward<Args>(args)...)
//	{
//		cout << sizeof...(args) << endl;
//	}
//};
//int main()
//{
//	//Person a("兔子", 45);
//	//ListNode<Person> l1(a);
//	//ListNode<Person> l3(move(a));
//	//ListNode<Person> l4("兔子", 45);
//	//ListNode<Person> l5({ "兔子", 45 }); 
//
//	Person p1("Alice", 30);
//	const Person p2("map", 40);
//	//调用万能引用构造，然后通过万能引用的构造调用Person的拷贝构造
//	ListNode<Person> node1(p1);
//	//调用const左值构造，然后通过ListNode的构造调用Person的拷贝构造
//	ListNode<Person> node2(p2);
//	//调用移动构造，然后通过ListNode的移动构造调用Person的拷贝构造
//	ListNode<Person> node3(std::move(p1));
//	//调用万能构造，因为是多参，所以ListNode的构造相当于_data(forward<Args>("Bob"), forward<Args>(25)),然后再调用Person的构造
//	ListNode<Person> node4("Bob", 25);
//	//{ "Bob", 25 }初始化列表。由于C++初始化列表是一个整体，会构造成对象，所以这里要注意的是上面的万能引用构造和移动构造不能同时出现，
//	//因为两个构造都满足将{ "Bob", 25 }进行构造。
//	//万能引用会实例化成const char*和int，然后调用Person的构造函数构造_data（多参构造，将这里的“构造+拷贝构造”优化成构造）
//	//移动构造会实例化成ListNode(Person &&)，先将{ "Bob", 25 }构造成Person对象，然后将Person对象拷贝赋值给_data
//	//这里的("Bob", 25)与{ "Bob", 25 }不同，("Bob", 25)是两个整体，即"Bob"和25，{ "Bob", 25 }是一个整体，即Person。
//	ListNode<Person> node5({ "Bob", 25 });
//
//	return 0;
//}